/**
 * @Description: 初始化地图
 * @Author: xubaoliang
 * @Date: 2022-05-12 09:19:27
 */
import gcoord from "gcoord";
import BMap from "./maps/bmap";
import AMap from "./maps/amap";
import SuperMap from "./maps/supermap";
import ArcGis from "./maps/arcgis";
import OpenStreetMap from "./maps/openStreetMap";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import { Style } from "ol/style";
import { DoubleClickZoom } from 'ol/interaction'
import { ScaleLine, Zoom, ZoomSlider } from "ol/control";
import GoogleMap from "@/plugins/map/maps/googleMap";

import globalConfigs from '@/utils/globalConfigs';



export function HiMap(elId, options) {
  // 初始化地图配置
  this.mapType = globalConfigs.MAPSETTINGS.MAPTYPE;
  this.mapCenter = globalConfigs.MAPSETTINGS.MAPCENTER;
  this.defaultZoom = globalConfigs.MAPSETTINGS.DEFAULTZOOM;
  this.maxZoom = globalConfigs.MAPSETTINGS.MAXZOOM;
  this.minZoom = globalConfigs.MAPSETTINGS.MINZOOM;
  this.mapTileUrl = globalConfigs.MAPSETTINGS.MAPTILEURL;
  this.mapStyle = globalConfigs.MAPSETTINGS.MAPSTYLE;
  this.mapKey = globalConfigs.MAPSETTINGS.MAPKEY;
  this.gcoordType = gcoord.WGS84;
  this.mapExtend = globalConfigs.MAPSETTINGS.MAPEXTEND || { minLongitude: 5, maxLongitude: 180, minLatitude: 5, maxLatitude: 90 };
  this.trafficInterval = null;
  // 地图对象
  this.elId = elId;
  this.map = null;
  this.init(elId, options);
}

HiMap.prototype = {
  constructor: HiMap,

  /**
   * 初始化地图
   * @param elId 地图绑定的domId
   * @param options {zoomFlag:true/false, scaleLineFlag: true/false,...}
   * 
   * @param options 描述: 1、是否显示缩放工具 zoomFlag:true/false 2、是否显示比例尺 scaleLineFlag: true/false
   */
  init(elId, options) {
    switch (this.mapType.toLowerCase()) {
      // 百度离线
      case 'bmap':
        // 百度在线地图
        this.gcoordType = gcoord.BD09Meter;
        this.map = BMap.init(elId, this, options);
        break;

      case 'bmapline':
        this.gcoordType = gcoord.BD09Meter;
        this.map = BMap.init(elId, this, options);
        break;
      case 'amap':
      case 'amapline':
        this.gcoordType = gcoord.GCJ02;
        this.map = AMap.init(elId, this, options);
        break;
      case 'supermap':
        this.gcoordType = gcoord.WGS84;
        this.map = SuperMap.init(elId, this, options);
        break;
      case 'arcgis':
        this.gcoordType = gcoord.WGS84;
        this.map = ArcGis.init(elId, this, options);
        break;
      case 'googlemap':
        this.gcoordType = gcoord.WGS84; // 国外使用的是WGS84坐标，国内使用的是GCJ02
        this.map = GoogleMap.init(elId, this, options);
        break;
      default:
        this.map = OpenStreetMap.init(elId, this, options);
        break;
    }
  },
  /**
   * 清空地图图层
   */
  clearMap() {
    this.map.getLayers().forEach(function (layer) {
      if (layer instanceof VectorLayer) {
        layer.getSource().clear();
      }
    });
  },
  /**
   * WGS84转地图坐标
   * @param coordinate
   * @returns {GeoJSON | Position}
   */
  transform(coordinate) {
    // ArcGis的坐标为WGS84,无须转换
    if (this.gcoordType == gcoord.WGS84) {
      return coordinate;
    }
    if (coordinate == null || coordinate === undefined || coordinate == ""
      || (!(coordinate instanceof Array) || coordinate.length != 2 || !this.checkExtend(coordinate[0], coordinate[1]))) {
      return coordinate;
    }
    return gcoord.transform(coordinate, gcoord.WGS84, this.gcoordType);
  },
  /**
   * 批量转换经纬为地图坐标
   * @param coordinates
   * @returns {*[]}
   */
  transformList(coordinates) {
    if (this.gcoordType == gcoord.WGS84) {
      return coordinates;
    }
    let list = []
    for (let i = 0; i < coordinates.length; i++) {
      if (coordinates[i] == null || coordinates[i] == undefined || coordinates[i] == ""
        || (!(coordinates[i] instanceof Array) || coordinates[i].length != 2 || !this.checkExtend(coordinates[i][0], coordinates[i][1]))) {
        continue;
      }
      else {
        list.push(gcoord.transform(coordinates[i], gcoord.WGS84, this.gcoordType));
      }
    }
    return list;
  },
  /**
   * 地图坐标转WGS84
   * @param coordinate
   * @returns {GeoJSON | Position}
   */
  transform2WGS84(coordinate) {
    if (globalConfigs.MAPSETTINGS.MAPTYPE === 'arcgis') {
      return coordinate;
    }
    return gcoord.transform(coordinate, this.gcoordType, gcoord.WGS84);
  },
  /**
   * 批量地图坐标转WGS84
   * @param coordinates
   * @returns {*[]}
   */
  transformList2WGS84(coordinates) {
    if (globalConfigs.MAPSETTINGS.MAPTYPE === 'arcgis') {
      return coordinates;
    }
    let list = []
    for (let i = 0; i < coordinates.length; i++) {
      list.push(gcoord.transform(coordinates[i], this.gcoordType, gcoord.WGS84));
    }
    return list;
  },
  /**
   * 刷新地图区域
   */
  updateSize() {
    let _this = this;
    setTimeout(function () {
      _this.map.updateSize();
    }, 10);
  },
  /**
   * 方向角转弧度
   * @param angler
   * @returns {number}
   */
  getRotation(angler) {
    return (parseInt(angler) - 90) * Math.PI / 180;
  },
  /**
   * 初始化业务图层
   * @param title
   * @param sourceOptions
   * @param styleOptions
   */
  createUserLayer(title, sourceOptions, styleOptions) {
    let layer = new VectorLayer({
      title: title,
      source: new VectorSource(sourceOptions),
      style: new Style(styleOptions),
      zIndex: 2
    });
    this.map.addLayer(layer);
    return layer;
  },
  /**
   * 禁用双击缩放地图操作
   */
  removeInteraction(type) {
    const interaction = this.map.getInteractions().getArray().find(interaction => {
      if (type === 'DoubleClickZoom') {
        return interaction instanceof DoubleClickZoom;
      }
      return false;
    });
    this.map.removeInteraction(interaction);
  },
  /**
   * 移除悬浮层
   * @param overlayId
   */
  removeOverlay(overlayId) {
    let overlay = this.map.getOverlayById(overlayId);
    if (overlay) {
      this.map.removeOverlay(overlay);
    }
  },
  /**
   * 检查经纬度是否在指定范围内，过滤异常数据,WGS84坐标
   * @param lon
   * @param lat
   * @return {boolean}
   */
  checkExtend(lon, lat) {
    if (lon == null || lon == undefined || lon == '' || lat == null || lat == undefined || lat == '') {
      return false
    }
    else if (isNaN(lon) || isNaN(lat)) {
      return false;
    } else if (lon == 0 && lat == 0) {
      return false;
    } else {
      return this.mapExtend.minLongitude <= lon && lon <= this.mapExtend.maxLongitude
        && this.mapExtend.minLatitude <= lat && lat <= this.mapExtend.maxLatitude;
    }
  },
  /**
   * 获取地图对象
   * @return {null}
   */
  getMap() {
    return this.hiMap.map || null;
  },
  /**
   * 添加比例尺工具条
   */
  addScaleLineControl() {
    let scaleLine = new ScaleLine({});
    this.map.addControl(scaleLine);
    let scaleLineObj = document.querySelector('#' + this.elId + ' .ol-scale-line-inner');
    if (scaleLineObj) {
      scaleLineObj.title = this.map.getView().getZoom();
    }
    this.map.getView().on('change', () => {
      if (scaleLineObj) {
        scaleLineObj.title = this.map.getView().getZoom();
      }
    });
  },
  /**
  * @Description: 缩放到某一级别
  * @Author: 王燕欣
  * @Date: 2025-01-05 21:59
  */

  controlZoomLevel(param){    
    this.map.getView().setZoom(Number(param)); // 设置缩放级别为5
  },

  /**
   * 添加缩放工具条
   */
  addZoomControl() {
    let zoom = new Zoom({
      zoomInTipLabel: window.vm.$i18n.t('lang.zoom_in'),
      zoomOutTipLabel: window.vm.$i18n.t('lang.zoom_out')
    });
    this.map.addControl(zoom);
    let zoomSlider = new ZoomSlider({});
    this.map.addControl(zoomSlider);
    let zoomSliderObj = document.querySelector('#' + this.elId + ' .ol-zoomslider-thumb');
    if (zoomSliderObj) {
      zoomSliderObj.title = this.map.getView().getZoom();
    }
    this.map.getView().on('change', () => {
      if (zoomSliderObj) {
        zoomSliderObj.title = this.map.getView().getZoom();
      }
    });
  },
  /**
   * 增加实时路况显示，仅支持在线地图
   */
  addMapTraffic() {
    let trafficLayer = null;
    switch (this.mapType.toLowerCase()) {
      case 'bmapline':
        trafficLayer = BMap.addTrafficLayer();
        break;
      case 'amapline':
        trafficLayer = AMap.addTrafficLayer();
        break;
      default:
        break;
    }
    if (trafficLayer) {
      this.map.addLayer(trafficLayer);
      if (this.trafficInterval) {
        clearInterval(this.trafficInterval);
        this.trafficInterval = null;
      }
      this.trafficInterval = window.setInterval(() => {
        trafficLayer.getSource().clear();
        this.updateSize();
      }, 30000);
    }
  },
  /**
   * 移除实时路况图层
   */
  removeMapTraffic() {
    this.map.getLayers().forEach(layer => {
      if (layer.get('id') === 'trafficLayer') {
        this.map.removeLayer(layer);
      }
    });
    if (this.trafficInterval) {
      clearInterval(this.trafficInterval);
      this.trafficInterval = null;
    }
  },
  /**
   * 增加实时路况预测，仅支持在线地图
   */
  addMapHistoryTraffic() {
    let trafficLayer = null;
    switch (this.mapType.toLowerCase()) {
      case 'bmapline':
        trafficLayer = BMap.addHistoryTrafficLayer(1, 10);
        break;
      case 'amapline':
        trafficLayer = AMap.addHistoryTrafficLayer(1, 10, 0);
        break;
      default:
        break;
    }
    if (trafficLayer) {
      this.map.addLayer(trafficLayer);
      if (this.trafficInterval) {
        clearInterval(this.trafficInterval);
        this.trafficInterval = null;
      }
      this.trafficInterval = window.setInterval(() => {
        trafficLayer.getSource().clear();
        this.updateSize();
      }, 30000);
    }
  },
  /**
   * 移除实时路况预测图层
   */
  removeMapHistoryTraffic() {
    this.map.getLayers().forEach(layer => {
      if (layer.get('id') === 'historyTrafficLayer') {
        this.map.removeLayer(layer);
      }
    });
    if (this.trafficInterval) {
      clearInterval(this.trafficInterval);
      this.trafficInterval = null;
    }
  },
  disposeMapLayer() {
    const layers = this.map.getLayers();
    while (layers.getLength() > 0) {
      const layer = layers.item(0);
      if (layer.get('layerSourceType') == 'VECTOR') {
        layer.getSource().clear();
      }
      layer.getRenderer().dispose();
      layer.getSource(null);
      this.map.removeLayer(layer);
    }
    this.map.setTarget(null);
    this.map = null;
  }
}

export default HiMap;
